package com.atguigu.gmall.order.service.impl;

import com.atguigu.gmall.cart.client.CartFeignClient;
import com.atguigu.gmall.common.util.HttpClientUtil;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.PaymentWay;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private CartFeignClient cartFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${ware.url}")
    private String wareUrl; //http://localhost:9001

    /**
     * 提交订单
     * @param orderInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveOrderInfo(OrderInfo orderInfo) {
        //编写insert业务逻辑
        //插入数据到orderInfo表
        //细节：total_amount,order_status,user_id,out_trade_no,trade_body,operate_time,expire_time,process_status
        orderInfo.sumTotalAmount();
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        String outTradeNo = "ATGUIGU" + System.currentTimeMillis() + "" + new Random().nextInt(1000);
        orderInfo.setOutTradeNo(outTradeNo);
        orderInfo.setTradeBody("结婚买房买车买手机");
        //将所有的商品名称进行拼接
        orderInfo.setOperateTime(new Date());
        orderInfo.setPaymentWay(PaymentWay.ONLINE.getComment());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, 1);
        orderInfo.setExpireTime(calendar.getTime());//+1天
        //在订单的进度状态中能够获取到订单状态
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
        orderInfoMapper.insert(orderInfo);

        //插入数据到orderDetail表
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        orderDetailList.stream().forEach(orderDetail -> {
            //删除购物车数据
            cartFeignClient.delCart(orderDetail.getSkuId().toString());
            //赋值订单id
            orderDetail.setOrderId(orderInfo.getId());
            orderDetailMapper.insert(orderDetail);
        });
        Long orderId = orderInfo.getId();
        //返回数据
        return orderId;
    }

    /**
     * 生成流水号
     * @param userId
     * @return
     */
    @Override
    public String getTradeNo(String userId) {
        //这个就是流水号
        String tradeNo = UUID.randomUUID().toString();
        //定义key
        String key = "tradeNoKey:"+userId;
        //存储到缓存中
        this.redisTemplate.opsForValue().set("tradeNoKey", tradeNo);
        return tradeNo;
    }

    /**
     * 比较流水号
     * @param tradeNo
     * @param userId
     * @return
     */
    @Override
    public Boolean checkTradeNo(String tradeNo, String userId) {
        //获取到缓存的流水号
        //定义key
        String key = "tradeNoKey:"+userId;
        String redisTradeNo = (String) this.redisTemplate.opsForValue().get(key);
        return tradeNo.equals(redisTradeNo);
    }

    /**
     * 删除缓存的流水号
     * @param userId
     */
    @Override
    public void delTradeNo(String userId) {
        //获取key
        String key = "tradeNokey:"+userId;
        this.redisTemplate.delete(key);
    }

    /**
     * 验证库存
     * @param skuId
     * @param skuNum
     * @return
     */
    @Override
    public Boolean checkStock(Long skuId, Integer skuNum) {
        String result = HttpClientUtil.doGet(wareUrl+"/hasStock/?skuId="+skuId+"&num="+skuNum);
        return "1".equals(result);
    }

    /**
     * 查看我的订单
     * @param pageParam
     * @param userId
     * @return
     */
    @Override
    public IPage<OrderInfo> getPage(Page<OrderInfo> pageParam, String userId) {
        //调用订单Mapper
        //显示的时候，需要显示当前这个订单明细
        IPage<OrderInfo> page = orderInfoMapper.selectPageByUserId(pageParam,userId);
        //获取显示用的订单状态

        //返回数据
        return page;
    }
}
